//==========================================================================
// Copyright (c) 2000-2008,  Elastos, Inc.  All Rights Reserved.
//==========================================================================

#ifndef __ELASTOS_CDISPLAY_H__
#define __ELASTOS_CDISPLAY_H__

#include <ddk.h>
#include "drvassistant.h"
#include "nu_api.h"
#include "display.h"

#define SCREEN_WIDTH            240
#define SCREEN_HEIGHT           400

inline UInt32 Size2Order(UInt32 size)
{
    UInt32 order = 0;
    UInt32 pageSize = PAGE_SIZE;

    while (pageSize < size) {
        pageSize <<= 1;
        order++;
    }

    return order;
}

typedef struct ConvertTable {
    UInt8 _color_table[256*3];
    Int32 Ym_tableEx[256];
    Int32 Um_blue_tableEx[256];
    Int32 Um_green_tableEx[256];
    Int32 Vm_green_tableEx[256];
    Int32 Vm_red_tableEx[256];
} ConvertTable;

class CDisplay : public CDeviceDriver
{
public:
    CDisplay() {
        m_Overlay = NULL;
        m_u32OverlaySize = 0;

        m_frameBuffer = NULL;
        m_u32FrameBufferSize = 0;

        memset(&m_rtOverlay, 0, sizeof(m_rtOverlay));
        m_bRendered = FALSE;
        m_vaOverlay = NULL;
        m_byTransLvl = 255;

        m_pConvertTable = NULL;

        m_orientation = ScreenOrientation_Up;

        m_teMode = FALSE;
    }

    ~CDisplay();

    ECode constructor();

    CARAPI Read(
        /* [in] */ Int64 offset,
        /* [in] */ Int32 bytesToRead,
        /* [out] */ MemoryBuf* pBuffer,
        /* [out] */ IEvent** ppCompletionEvent) {
        return E_NOT_IMPLEMENTED;
    }

    CARAPI Write(
        /* [in] */ Int64 offset,
        /* [in] */ const MemoryBuf &buffer,
        /* [out] */ Int32* pBytesWritten,
        /* [out] */ IEvent** ppCompletionEvent) {
        return E_NOT_IMPLEMENTED;
    }

    CARAPI Control(
        /* [in] */ Handle32 controlCode,
        /* [in] */ const MemoryBuf &inBuffer,
        /* [out] */ MemoryBuf* pOutBuffer,
        /* [out] */ IEvent** ppCompletionEvent);

    virtual void Dispose(){}

private:

    ECode InitDisplayHardware(
        /* [in] */ const MemoryBuf &ebbInData,
        /* [out] */ MemoryBuf* outData);

    ECode GetBaseplane(
        /* [in] */ const MemoryBuf &ebbInData,
        /* [out] */ MemoryBuf* outData);

    ECode EnableOverlay(
        /* [in] */ const MemoryBuf &ebbInData,
        /* [out] */ MemoryBuf* outData);

    ECode GetOverlay(
        /* [in] */ const MemoryBuf &ebbInData,
        /* [out] */ MemoryBuf* outData);

    ECode DisableOverlay(
        /* [in] */ const MemoryBuf &ebbInData,
        /* [out] */ MemoryBuf* outData);

    ECode Render(
        /* [in] */ const MemoryBuf &ebbInData,
        /* [out] */ MemoryBuf* outData);

    ECode RenderOverlay(
        /* [in] */ const MemoryBuf &ebbInData,
        /* [out] */ MemoryBuf* outData);

    ECode SetLayerTransparence(
        /* [in] */ const MemoryBuf &ebbInData,
        /* [out] */ MemoryBuf* outData);

    ECode SetOrientation(
        /* [in] */ const MemoryBuf &ebbInData,
        /* [out] */ MemoryBuf* outData);

    ECode SetTEModeEnabled(
        /* [in] */ const MemoryBuf &ebbInData,
        /* [out] */ MemoryBuf* outData);

    ECode GetOverlayOut(
        /* [in] */ Int32 n32Layer,
        /* [in] */ MemoryBuf * outData);

    Void CombineOverlay_ARGB(
        /* [in] */ PUInt8 pu8SrcBuffer,
        /* [in] */ Rectangle * prtOverlay);

    Void CombineOverlay_RGB565(
        /* [in] */ PUInt8 pu8SrcBuffer,
        /* [in] */ Rectangle * prtOverlay);

    Void CombineOverlay_YUYV(
        /* [in] */ PUInt8 pu8SrcBuffer,
        /* [in] */ Rectangle * prtOverlay);

    Void CombineOverlay_YCbCr422(
        /* [in] */ PUInt8 pu8SrcBuffer,
        /* [in] */ Rectangle * prtOverlay);

    Void CombineOverlayToFrameBuffer(
        /* [in] */ PUInt8 pu8SrcBuffer,
        /* [in] */ Rectangle * prtFrame);

    UInt8 border_color(
        /* [in] */ long color);

    Void Init_color_table();

    Void RenderAll(
        /* [in] */ UInt8* address);
public:

    DzMutex m_Mutex;
    UInt8* m_Overlay;
    UInt32 m_u32OverlaySize;

    UInt8* m_frameBuffer;
    UInt32 m_u32FrameBufferSize;

    OverlayFormat m_OverlayFormat;
    Rectangle m_rtOverlay;
    Boolean m_bRendered;
    Address m_vaOverlay;
    Byte m_byTransLvl;

    // convert table
    ConvertTable * m_pConvertTable;
    UInt8 * color_table;
    UInt8 * _color_table;           // 256 * 3
    Int32 * Ym_tableEx;             // 256
    Int32 * Um_blue_tableEx;        // 256
    Int32 * Um_green_tableEx;       // 256
    Int32 * Vm_green_tableEx;       // 256
    Int32 * Vm_red_tableEx;         // 256

    ScreenOrientation m_orientation;
    Boolean m_teMode;
};

#endif // __ELASTOS_DISPLAY_H__
